﻿
using ActionSystem.Core.Utils;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;

namespace ActionSystem.Core
{
    /// <summary>
    /// 与状态无关的全局Action，
    /// buff
    /// 或者其他个体与该个体进行数据交互或者
    /// </summary>
    [PoolInitAttribute(typeof(GeneticPool<BasePassiveAction>), 50)]
    public sealed class BasePassiveAction:IPoolItem
    {
        bool inited = false;
        public bool Inited => inited;

        public BasePassiveActionConfig config;
        public BasePassiveActionConfig Config => config;
        public BasePassiveActionHandler handler;
        public BasePassiveActionHandler Handler => handler;
        public BasePassiveAction(BasePassiveActionConfig config)
        {
            this.config = config;
            this.handler = GetActionHandler(config.GetType()); 
        }
        public BasePassiveAction()
        {
        }
        public void SetUp(BasePassiveActionConfig config)
        {
            this.config = config;
            this.handler = GetActionHandler(config.GetType());
        }
        /// <summary>
        /// 初始化
        /// </summary>
        public void Init(BaseStateMachine stateMachine)
        {
            Handler?.Begin(Config,stateMachine);
            inited = true;
        }
        bool ended = false;
        public bool Ended => ended;

        

        /// <summary>
        /// 设置可以被移除
        /// </summary>
        public void Remove(BaseStateMachine stateMachine)
        {
            Handler?.End(Config,stateMachine);
            //放回缓存
            PutbackPassiveActionHandler(Handler);
            ended = true;
        }
        /// <summary>
        /// 更新
        /// </summary>
        /// <param name="stateMachine">当前状态机</param>
        /// <param name="updateLogicAction">是否更新到下一个逻辑帧</param>
        /// <param name="deltaTime"></param>
        public void Update(BaseStateMachine stateMachine, bool updateLogicAction, float deltaTime)
        {
            Handler?.Update(Config,stateMachine,updateLogicAction,deltaTime);
        }
        /// <summary>
        /// 判断是否结束
        /// </summary>
        /// <param name="stateMachine"></param>
        /// <returns></returns>
        public bool CheckEnd(BaseStateMachine stateMachine)
        {
            if(Handler==null)
            {
                return false;
            }
            return Handler.CheckEnd(Config, stateMachine);
        }

        /// <summary>
        /// 缓存handler
        /// </summary>
        private static Dictionary<Type, List<BasePassiveActionHandler>> handlerCache = new Dictionary<Type, List<BasePassiveActionHandler>>();


        /// <summary>
        /// 获取handler
        /// </summary>
        /// <param name="type"></param>
        /// <returns></returns>
        private static BasePassiveActionHandler GetActionHandler(Type type)
        {
            BasePassiveActionHandler handler = null;

            //具有该参数的类type->Attribute->IIActionHandler
            PassiveActionConfigAttribute config = type.GetCustomAttribute<PassiveActionConfigAttribute>(true);

            Type handlerType = config.handlerType;

            if (!handlerCache.ContainsKey(handlerType))
            {
                handlerCache.Add(handlerType, new List<BasePassiveActionHandler>());
            }
            var cache = handlerCache[handlerType];
            if (cache.Count > 0)//从缓存中取出
            {
                handler = cache[cache.Count - 1];
                cache.RemoveAt(cache.Count - 1);
            }
            else
            {
                //实例化该类
                handler = Activator.CreateInstance(handlerType) as BasePassiveActionHandler;
            }

            if (handler == null)
            {
                throw new System.Exception($"{handlerType} 类型未继承 {nameof(BasePassiveActionHandler)} 接口");
            }
            else
            {
                handler.Reset();
            }

            return handler;
        }
        /// <summary>
        /// 放回池子
        /// </summary>
        /// <param name="type"></param>
        /// <param name="handler"></param>
        private static void PutbackPassiveActionHandler(BasePassiveActionHandler handler)
        {
            if (handler == null)
            {
                return;
            }
            Type handlerType = handler.GetType();

            if (!handlerCache.ContainsKey(handlerType))
            {
                handlerCache.Add(handlerType, new List<BasePassiveActionHandler>());
            }
            var cache = handlerCache[handlerType];
            cache.Add(handler);
        }
        #region IPoolItem
        public bool IsDeleted { get; set; }
        public void PoolItemReset()
        {
            inited = false;        
            config = null;
            handler = null;
            ended = false;
        }

        public void PoolItemDelete()
        {
            GeneticPool<BasePassiveAction>.Delete(this);
        }
        #endregion
    }
}
